package com.letoken.platform.app.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.letoken.platform.app.service.AppUserIssueRecordService;
import com.letoken.platform.pub.constant.RedisKeyConstant;
import com.letoken.platform.pub.enums.LetokenApiResponseEnum;
import com.letoken.platform.pub.enums.LetokenTokenTypeEnum;
import com.letoken.platform.pub.enums.TokenTransactionTypeEnum;
import com.letoken.platform.pub.exception.ApiServiceException;
import com.letoken.platform.pub.util.BigDecimalUtil;
import com.letoken.platform.repo.admin.dao.AdminIssueConfigMapper;
import com.letoken.platform.repo.admin.manager.AdminIssueConfigManager;
import com.letoken.platform.repo.admin.po.AdminIssueConfig;
import com.letoken.platform.repo.app.dao.*;
import com.letoken.platform.repo.app.po.*;
import com.letoken.platform.app.service.*;

import com.letoken.platform.repo.app.redis.RedisConfig;
import com.letoken.platform.repo.app.req.user.UserLevelReq;
import com.letoken.platform.repo.app.res.config.QueryAppIssueConfigRes;
import com.letoken.platform.repo.helper.CalculateConsumerValue;
import com.letoken.platform.repo.mall.dao.AppIssueCardInfoMapper;
import com.letoken.platform.repo.mall.dao.AppMallIssueMapper;
import com.letoken.platform.repo.mall.po.AppIssueCardInfo;
import com.letoken.platform.repo.utlis.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.MessageFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * Le账户-用户铸币发行信息 服务实现类
 * </p>
 *
 * @author 作者
 * @since 2022-12-10
 */
@Slf4j
@Service
public class AppUserIssueServiceImpl extends ServiceImpl<AppUserIssueMapper, AppUserIssue> implements AppUserIssueService {

    @Resource
    private AppUserIssueMapper appUserIssueMapper;


    @Autowired
    private AppUserIssueRecordService appUserIssueRecordService;

    @Autowired
    private AppUserCirculateService appUserCirculateService;

    @Autowired
    private AppUserWalletService appUserWalletService;

    @Autowired
    private AppUserAssetsHistoryService appUserAssetsHistoryService;

    @Resource
    private AppUserTeamMapper appUserTeamMapper;

    @Resource
    private AppEcoLevelMapper appEcoLevelMapper;

    @Resource
    private AppUserTeamPathMapper appUserTeamPathMapper;

    @Autowired
    private AppUserCirculateAccelerateService appUserCirculateAccelerateService;

    @Autowired
    private AppUserTeamService appUserTeamService;

    @Autowired
    private AppUserIssueHistoryService appUserIssueHistoryService;

    @Resource
    private RedisConfig redisConfig;

    @Resource
    private AdminIssueConfigManager adminIssueConfigManager;

    @Resource
    private AppUserLogService appUserLogService;

    @Resource
    AppUserWalletMapper appUserWalletMapper;
    @Autowired
    CalculateConsumerValue calculateConsumerValue;

    /**
     * 修改
     *
     * @param issueAmount       已发行数量
     * @param circulationAmount 已流通数量
     * @param circulationRemain 待流通数量
     * @param userId
     * @return
     */
    @Override
    public int updateUserIssueByUseIid(BigDecimal issueAmount, BigDecimal circulationAmount, BigDecimal circulationRemain, Integer userId, Integer countDown, Integer rewardTime) {
        String key = RedisKeyConstant.UPDATE_APP_USER_ISSUE + userId;
        int rulest;
        RedissonClient redissonClient = redisConfig.getRedisson();
        RLock rlock = redissonClient.getLock(key);
        try {
            rlock.lock(5, TimeUnit.SECONDS);
            AppUserIssue appUserIssue = appUserIssueMapper.selectById(userId);
            if (appUserIssue.getIssueAmount().add(issueAmount).compareTo(BigDecimal.ZERO) < 0) {
                throw new ApiServiceException(MessageFormat.format("铸币余额{0}少于请求金额{1}", appUserIssue.getIssueAmount(), issueAmount));
            }
            if (appUserIssue.getCirculationRemain().add(circulationRemain).compareTo(BigDecimal.ZERO) < 0) {
                throw new ApiServiceException(MessageFormat.format("待流通余额{0}少于请求金额{1}", appUserIssue.getCirculationRemain(), circulationRemain));
            }
            if (appUserIssue.getCirculationAmount().add(circulationAmount).compareTo(BigDecimal.ZERO) < 0) {
                throw new ApiServiceException(MessageFormat.format("已流通余额{0}少于请求金额{1}", appUserIssue.getCirculationAmount(), circulationAmount));
            }
            rulest = appUserIssueMapper.updateUserIssueByUseIid(issueAmount, circulationAmount, circulationRemain, userId, appUserIssue.getVersion(), countDown, rewardTime);
        } finally {
            if (rlock != null && rlock.isHeldByCurrentThread()) {
                rlock.unlock();
            }
        }
        return rulest;
    }

    /**
     * 周期奖励增加记录
     *
     * @param userId            推荐人id
     * @param rate              释放比例
     * @param releaseType       释放类型 1。周期  2。分享
     * @param circulateDuration 释放周期  分
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void sharingCirculationRewards(Integer userId, BigDecimal rate, Integer releaseType, Integer circulateDuration) {
        //查询所有为流通结束的订单
        QueryWrapper<AppUserIssueRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("status", 0);
        List<AppUserIssueRecord> recordList = appUserIssueRecordService.list(queryWrapper);
        if (recordList == null || recordList.size() == 0) {
            return;
        }
        //加速总金额
        BigDecimal sumAmount = new BigDecimal("0");
        List<AppUserIssueRecord> list = new ArrayList<>();
        //修改订单记录
        for (AppUserIssueRecord record : recordList) {
            AppUserIssueRecord issueRecord = new AppUserIssueRecord();
            BigDecimal amount = record.getIssueAmount().multiply(rate);
            BigDecimal name = record.getWaitCirculation().divide(amount, BigDecimal.ROUND_HALF_EVEN)/*.setScale(6, BigDecimal.ROUND_HALF_UP)*/;
            String[] decimals = name.toString().split("\\.");
            issueRecord.setRound(new BigDecimal(decimals[1]).compareTo(new BigDecimal("0")) == 0 ? Integer.parseInt(decimals[0]) : Integer.parseInt(decimals[0]) + 1);
            //如果当前订单生育释放金额  小于每期数量则释放剩下全部   反之  按照每期释放金额进行释放
            if (amount.compareTo(record.getWaitCirculation()) > 0) {
                amount = record.getWaitCirculation();
                sumAmount = sumAmount.add(amount);
            } else {
                sumAmount = sumAmount.add(amount);
            }

          /*  issueRecord.setCirculation(record.getCirculation().add(amount).compareTo(record.getIssueAmount()) > 0 ? record.getIssueAmount().multiply(new BigDecimal("2")) : record.getCirculation().add(amount));
            issueRecord.setWaitCirculation(record.getWaitCirculation().subtract(amount).compareTo(new BigDecimal("0")) >= 0 ? record.getWaitCirculation().subtract(amount) : new BigDecimal("0"));*/
            issueRecord.setCirculation(record.getCirculation().add(amount));
            issueRecord.setWaitCirculation(record.getWaitCirculation().subtract(amount));
            issueRecord.setCirculateRound(record.getCirculateRound() + 1);
            issueRecord.setStatus(issueRecord.getWaitCirculation().compareTo(BigDecimal.ZERO) == 0 ? 1 : 0);
            issueRecord.setUpdateTime(LocalDateTime.now());
            issueRecord.setId(record.getId());
            issueRecord.setAmount(amount);
            list.add(issueRecord);
        }


        boolean updateFlag = appUserIssueRecordService.updateBatchById(list);
        if (!updateFlag) {
            log.error("修改订单记录失败！用户id：{},奖励类型：{},订单数量：{}", userId, releaseType, recordList.size());
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        //增加流通记录
        List<AppUserCirculate> appUserCirculates = new ArrayList<>();
        for (AppUserIssueRecord record : list) {
            AppUserCirculate appUserCirculate = new AppUserCirculate();
            appUserCirculate.setIsssueId(record.getId());
            appUserCirculate.setUserId(userId);
            appUserCirculate.setCirculateType(releaseType);
            appUserCirculate.setCirculateRound(record.getCirculateRound());
            appUserCirculate.setCirculateAmount(record.getAmount());
            appUserCirculate.setCreateTime(LocalDateTime.now());
            appUserCirculate.setWaitCirculation(record.getWaitCirculation());
            appUserCirculate.setCirculateRoundRemain(record.getRound() - 1);
            appUserCirculates.add(appUserCirculate);
        }

        AppUserAssetsHistory appUserAssetsHistory = new AppUserAssetsHistory();
        appUserAssetsHistory.setUserId(userId);
        appUserAssetsHistory.setType(releaseType.equals(1) ? 4 : 5);
        appUserAssetsHistory.setStatus(1);
        appUserAssetsHistory.setTokenId(2);
        appUserAssetsHistory.setAmount(sumAmount);
        appUserAssetsHistory.setCreateTime(LocalDateTime.now());
        appUserAssetsHistory.setUpdateTime(LocalDateTime.now());
        boolean saveHistory = appUserAssetsHistoryService.save(appUserAssetsHistory);
        if (!saveHistory) {
            log.error("增加历史交易日志失败！app_user_assets_history 用户id：{},奖励类型：{},增加流通数量：{}", userId, releaseType.equals(1) ? 4 : 5, sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }
        AppUserIssueHistory appUserIssueHistory = new AppUserIssueHistory();
        appUserIssueHistory.setUserId(userId);
        appUserIssueHistory.setType(4);
        appUserIssueHistory.setAmount(sumAmount.negate());
        appUserIssueHistory.setCreateTime(LocalDateTime.now());
        appUserIssueHistoryService.save(appUserIssueHistory);
        boolean saveFlag = appUserCirculateService.saveBatch(appUserCirculates);
        if (!saveFlag) {
            log.error("增加流通记录失败！app_user_circulate 用户id：{},奖励类型：{},增加流通数量：{}", userId, releaseType, appUserCirculates.size());
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        int updateWallet = appUserWalletService.updateUserAmountByUserIDandCoin(sumAmount, new BigDecimal("0"), sumAmount.negate(), userId, LetokenTokenTypeEnum.LET.getId());
        if (updateWallet == 0) {
            log.error("修改用户金额失败 app_user_wallet！用户id：{},奖励类型：{},修改金额：{}", userId, releaseType, sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }


        try {
            AppUserAssetsHistory updateAssetHistory = new AppUserAssetsHistory();
            updateAssetHistory.setBalance(appUserWalletMapper.getAvailableBalance(appUserAssetsHistory.getTokenId(), appUserAssetsHistory.getUserId()));
            updateAssetHistory.setId(appUserAssetsHistory.getId());
            updateAssetHistory.updateById();
        }catch (Exception e){
            log.error("更新余额失败 id{} eMsg{}", appUserAssetsHistory.getId(), e.getMessage());
        }


        int updateUserIssue = this.updateUserIssueByUseIid(new BigDecimal("0"), sumAmount, sumAmount.negate(), userId, releaseType.equals(1) ? circulateDuration : null, releaseType.equals(1) ? 1 : null);
        if (updateUserIssue == 0) {
            log.error("修改用户铸币发型信息 app_user_issue！用户id：{},修改金额：{}", userId, sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }
    }

    /**
     * 更改用户等级  和 生态建设值
     *
     * @param userId    用户id
     * @param amount    发型let数量
     * @param inviterId 上级id
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void upgrade(Integer userId, BigDecimal amount, Integer inviterId, Integer type) {
        List<AppEcoLevel> appEcoLevelList = appEcoLevelMapper.getAppEcoLevelInfo();
        if (appEcoLevelList.size() <= 0 || appEcoLevelList == null) {
            return;
        }


        //推荐人下面  个人建设值最大的用户
        AppUserTeam teamMAX = appUserTeamMapper.getUserMaxValue(inviterId);
        AppUserTeam appUserTeam = appUserTeamMapper.getUserLevel(inviterId);
        int level = appUserTeam.getEcoLevel();
        BigDecimal bigDecimal = appUserTeam.getEcoValue();
        //如果最大团队建设值 等于  当前铸币人  则获取 其他团队建设值 之和
        BigDecimal sumValue = appUserTeamMapper.getSumValue(inviterId, teamMAX.getUserId());

        AppUserLog appUserLog = new AppUserLog();
        appUserLog.setUserId(inviterId);
        appUserLog.setTriggerId(userId);
        appUserLog.setCreateTime(LocalDateTime.now());
        appUserLog.setType(type);

        if (sumValue.compareTo(BigDecimal.ZERO) <= 0) {
            if (type.equals(1)) {
                appUserLog.setRemarks(String.format("绑定用户: %s，上级用户：%s。用户 %s绑定推荐人 %s，大区建设值%s，大区用户：%s。大区用户是被推荐人，所以不修改发生态建设值和奖励", userId, inviterId, userId, inviterId, teamMAX.getUserValue(), teamMAX.getUserId()));
            } else {
                appUserLog.setRemarks(String.format("铸币用户: %s，上级用户：%s。用户%s铸币%s， 大区建设值%s，大区用户：%s。大区用户是铸币人，所以不修改发生态建设值和奖励", userId, inviterId, userId, amount, teamMAX.getUserValue(), teamMAX.getUserId()));
            }
            appUserLogService.save(appUserLog);
            return;
        }
        //该推荐人 团队信息
        for (AppEcoLevel appEcoLevel : appEcoLevelList) {
            if (sumValue.compareTo(new BigDecimal(appEcoLevel.getEcoValue().toString())) >= 0) {
                appUserTeam.setEcoLevel(appEcoLevel.getLevel());
                break;
            }

        }
        appUserTeam.setEcoValue(sumValue);
        int bool = appUserTeamMapper.updateById(appUserTeam);
        if (bool == 0) {
            log.info("修改用户等级记录 app_user_issue！用户id：{},被推荐人id", inviterId, userId);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }
        if (type.equals(1)) {
            appUserLog.setRemarks(String.format("绑定用户: %s，上级用户：%s。用户 %s绑定推荐人 %s。推荐人等级修改为%s，生态建设值修改为%s,推荐人等级修改前%s,推荐人等级修改后%s", userId, inviterId, userId, inviterId, appUserTeam.getEcoLevel(), appUserTeam.getEcoValue(), level, bigDecimal));
        } else {
            appUserLog.setRemarks(String.format("铸币用户: %s，上级用户：%s。用户%s铸币%s。推荐人等级修改为%s，生态建设值修改为%s,推荐人等级修改前%s,推荐人等级修改后%s", userId, inviterId, userId, amount, appUserTeam.getEcoLevel(), appUserTeam.getEcoValue(), level, bigDecimal));
        }
        appUserLogService.save(appUserLog);

    }

    /**
     * 团队动态奖励
     *
     * @param appUserTeam
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void ecologicalRewards(AppUserTeam appUserTeam) {

        if (appUserTeam.getInviterId().equals(0)) {
            return;
        }
        BigDecimal amount = appUserTeam.getAmount();
        BigDecimal rate = appUserTeam.getRate();
        AppUserTeamPath appUserTeamPath = appUserTeamPathMapper.selectById(appUserTeam.getUserId());
        if (StringUtils.isEmpty(appUserTeamPath.getInvitePath()) || appUserTeamPath.getInvitePath().equals("0")) {
            return;
        }
        String[] path = appUserTeamPath.getInvitePath().split(",");
        // Integer id = appUserTeam.getUserId();
        QueryAppIssueConfigRes adminIssueConfig = adminIssueConfigManager.queryLetokenIssueConfig();
        Integer duration = adminIssueConfig.getCirculateDuration() * 24 * 60;

        // Integer duration = 2;
        // QueryAppIssueConfigRes queryLetokenIssueConfig = adminIssueConfigMapper.queryLetokenIssueConfig();
        Integer id = appUserTeamPath.getUserId();
        for (String inviteID : path) {
            Integer invite = Integer.parseInt(inviteID);
            BigDecimal down = new BigDecimal(duration);
            if (StringUtils.isEmpty(inviteID)) {
                id = invite;
                continue;
            }
            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setUserId(Integer.parseInt(inviteID));
            appUserLog.setTriggerId(appUserTeam.getUserId());
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setType(5);
            //查询 该推荐人最大的一笔团队业绩
            List<AppUserTeam> team = appUserTeamMapper.getMAXTeamValueSize(invite);
            if (team == null || team.size() == 0) {
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s，上级%s没有团队业绩，不获取奖励", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID));
                appUserLogService.save(appUserLog);
                continue;
            } else if (team.size() == 1) {
                AppUserTeam teams = team.get(0);
                Integer amout = appUserTeamMapper.getSUMTeamValue(invite, teams.getUserId());
                if (team == null) {
                    id = invite;
                    appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s，上级%s没有团队业绩，不获取奖励", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID));
                    appUserLogService.save(appUserLog);
                    continue;
                }
                if (teams.getUserId().equals(id) && !teams.getTeamValue().equals(amout)) {
                    id = invite;
                    appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。该铸币人属于最大团队业绩，所以不获取奖励,上级%s最大团队业绩%s，", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), team.get(0).getTeamValue(), inviteID));
                    appUserLogService.save(appUserLog);
                    continue;
                }
            }


            if (appUserTeamMapper.getCount(id, invite) < 0) {
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。该铸币人属于最大团队业绩，所以不获取奖励,上级%s最大团队业绩%s，", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), team.get(0).getTeamValue(), inviteID));
                appUserLogService.save(appUserLog);
                continue;
            }

            //查询推荐人团队信息
            AppUserTeam appUserTeam1 = appUserTeamMapper.selectById(invite);
            /*if (appUserTeam1.getEcoLevel() < 1) {
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。上级%s等级小于1级，不获取奖励", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID));
                appUserLogService.save(appUserLog);
                continue;
            }*/
            // AppEcoLevel appEcoLevel = appEcoLevelList.stream().filter(list -> !list.getLevel().equals(appUserTeam1.getEcoLevel())).collect(Collectors.toList()).get(0);
            //查询推荐人  铸币信息
            AppUserIssue appUserIssue = appUserIssueMapper.selectById(invite);
            AppUserTeam appUserTeam2 = appUserTeamMapper.selectById(invite);
            if (appUserTeam2.getUserAchievement() == null || appUserTeam2.getUserAchievement().equals(0) || appUserIssue == null || appUserIssue.getCirculationRemain().compareTo(BigDecimal.ZERO) <= 0) {
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。上级%s个人业绩为0，不获取奖励", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID));
                appUserLogService.save(appUserLog);
                continue;
            }
            BigDecimal dailiutong = appUserIssue.getCirculationRemain();
            log.info(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。当前获取奖励用户 %s,下级用户 %s", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID, id));

            //加速时间   被推荐人铸币金额/推荐人待流通数量
            BigDecimal decimal = amount.multiply(new BigDecimal(adminIssueConfig.getCirculateDuration() * 24 * 60)).divide(appUserIssue.getCirculationRemain().divide(new BigDecimal("2")), 2, RoundingMode.HALF_UP);
            //距离下个周期释放时间
            Duration durations = Duration.between(appUserIssue.getRewardTime().plusMinutes(appUserIssue.getCountDown()), LocalDateTime.now());
            //距离下个周期释放时间
            BigDecimal countDown = new BigDecimal(Math.abs((int) durations.toMinutes()));
            //如果加速时间 小于  下一个周期释放时间  下个周期释放时间 = 下个周期释放时间 - 加速时间
            if (decimal.compareTo(countDown) < 0) {
                countDown = countDown.subtract(decimal);
                int updateUserIssue = this.updateUserIssueByUseIid(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, invite, countDown.intValue(), 0);
                if (updateUserIssue == 0) {
                    throw new ApiServiceException(500, "mint失败，请稍后再试！");
                }
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。上级%s获得加速时间：%s，当前等级：%s,当前个人业绩：%s，当前距离下个周期释放时间：%s,加速后距离下个周期释放时间：%s", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID, decimal, appUserTeam1.getEcoLevel(), appUserTeam2.getUserAchievement(), appUserIssue.getCountDown(), countDown));
                appUserLogService.save(appUserLog);

                AppUserIssueHistory appUserIssueHistory = new AppUserIssueHistory();
                appUserIssueHistory.setUserId(invite);
                appUserIssueHistory.setType(6);
                appUserIssueHistory.setAmount(decimal);
                appUserIssueHistory.setNewTeamIssue(appUserTeam.getAmount());
                appUserIssueHistory.setWaitCirculation(dailiutong);
                appUserIssueHistory.setOperateUserId(appUserTeam.getUserId());
                appUserIssueHistory.setCreateTime(LocalDateTime.now());
                appUserIssueHistoryService.save(appUserIssueHistory);
            } else if (decimal.compareTo(countDown) >= 0 && decimal.compareTo(down) < 0) {//如果加速时间 大于等于  下一个周期释放时间 切小于  整个周期加速时间 直接释放  下个周期释放时间 = 重新计时
                //周期释放时间 -  加速时间  =  下个周期释放时间
                this.acceleratedRelease(invite, 1, down.subtract(decimal.subtract(countDown)).intValue(), decimal, decimal, amount, rate, 1, appUserLog);
            } else {//如果加速时间 大于  下一个周期释放时间 直接释放 释放几期 视推荐人等级而定  3期封顶
                if (decimal.compareTo(down) == 0) {
                    this.acceleratedRelease(invite, 1, null, decimal, decimal, amount, rate, 0, appUserLog);
                }
                if (decimal.compareTo(down) > 0) {//加速时间 大于  固定周期释放时间
                    BigDecimal result = decimal.divide(down, 2, RoundingMode.HALF_UP);
                    String[] strings = result.toString().split("\\.");
                    BigDecimal cycle = new BigDecimal(strings[0]);
                    BigDecimal time = BigDecimal.ZERO;
                    if (strings.length > 1) {
                        if (strings[1] != null && new BigDecimal(strings[1]).compareTo(BigDecimal.ZERO) > 0) {
                            time = new BigDecimal(strings[1]).divide(new BigDecimal(100)).multiply(down);
                        }
                    }
                    /*if (appUserTeam1.getEcoLevel().equals(1)) {
                        this.acceleratedRelease(invite, 1, null, new BigDecimal("1"), decimal, amount, rate, 0, appUserLog);
                    } else if (appUserTeam1.getEcoLevel().equals(2)) {
                        if (cycle.compareTo(new BigDecimal("2")) >= 0) {
                            this.acceleratedRelease(invite, 2, null, cycle, decimal, amount, rate, 0, appUserLog);
                        } else {
                            String str = "1" + "." + time;
                            this.acceleratedRelease(invite, 1, Integer.parseInt(countDown.subtract(time).toString()), new BigDecimal(str), decimal, amount, rate, 1, appUserLog);
                        }
                    } else if (appUserTeam1.getEcoLevel().equals(3)) {
                        if (cycle.compareTo(new BigDecimal("3")) >= 0) {
                            this.acceleratedRelease(invite, 3, null, cycle, decimal, amount, rate, 0, appUserLog);
                        } else {*/
                    String str = cycle + "." + time;
                    if (time.compareTo(countDown) >= 0) {
                        this.acceleratedRelease(invite, cycle.add(new BigDecimal("1")).intValue(), time.compareTo(countDown) == 0 ? down.intValue() : down.subtract((time.subtract(countDown))).intValue(), decimal, decimal, amount, rate, 1, appUserLog);
                    } else {
                        this.acceleratedRelease(invite, cycle.intValue(), countDown.subtract(time).intValue(), decimal, decimal, amount, rate, 0, appUserLog);
                    }
                    //}
                    //}
                }
            }
            id = invite;
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void mintRewards(Integer userId, BigDecimal rate, BigDecimal amounts, Integer id) {
        BigDecimal money = rate.multiply(amounts);
        AppUserIssue appUserIssue = appUserIssueMapper.selectById(userId);
        if (appUserIssue == null || appUserIssue.getCirculationRemain().compareTo(BigDecimal.ZERO) <= 0) {
            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setType(4);
            appUserLog.setUserId(userId);
            appUserLog.setTriggerId(id);
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setRemarks(String.format("铸币用户：%s，直推用户：%s。用户%s铸币%s，直推用户%s获得分享奖励。释放比例：%s * 铸币金额：%s = 奖励%s。实际奖励金额：%s.直推用户待释放额度为0，不获取奖励", id, userId, id, amounts, userId, rate, amounts, money, "0"));
            appUserLogService.save(appUserLog);
            return;

        }
        BigDecimal release;
        if (money.compareTo(appUserIssue.getCirculationRemain()) <= 0) {
            release = money;
        } else {
            release = appUserIssue.getCirculationRemain();
        }

        QueryWrapper<AppUserIssueRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("status", 0).orderByAsc("create_time");
        List<AppUserIssueRecord> recordList = appUserIssueRecordService.list(queryWrapper);
        if (recordList == null || recordList.size() == 0) {
            return;
        }
        List<AppUserIssueRecord> list = new ArrayList<>();
        //修改订单记录
        BigDecimal money2 = release;
        for (AppUserIssueRecord record : recordList) {
            if (money2.compareTo(BigDecimal.ZERO) <= 0) {
                break;
            }
            AppUserIssueRecord issueRecord = new AppUserIssueRecord();
            BigDecimal amount = record.getIssueAmount().multiply(rate);
            BigDecimal name = record.getWaitCirculation().divide(amount, BigDecimal.ROUND_HALF_EVEN);
            String[] decimals = name.toString().split("\\.");
            issueRecord.setRound(new BigDecimal(decimals[1]).compareTo(new BigDecimal("0")) == 0 ? Integer.parseInt(decimals[0]) : Integer.parseInt(decimals[0]) + 1);
            if (money2.compareTo(record.getWaitCirculation()) > 0) {
                issueRecord.setWaitCirculation(BigDecimal.ZERO);
                issueRecord.setCirculation(record.getWaitCirculation().add(record.getCirculation()));
                money2 = money2.subtract(record.getWaitCirculation());
            } else {
                issueRecord.setWaitCirculation(record.getWaitCirculation().subtract(money2));
                issueRecord.setCirculation(record.getCirculation().add(money2));
            }

            issueRecord.setCirculateRound(record.getCirculateRound() + 1);
            issueRecord.setStatus(issueRecord.getWaitCirculation().compareTo(BigDecimal.ZERO) == 0 ? 1 : 0);
            issueRecord.setUpdateTime(LocalDateTime.now());
            issueRecord.setId(record.getId());
            issueRecord.setAmount(money2);
            list.add(issueRecord);
        }

        boolean updateFlag = appUserIssueRecordService.updateBatchById(list);
        if (!updateFlag) {
            log.info("分享奖励 修改订单记录失败！用户id：{},奖励类型：{},订单数量：{}", userId, recordList.size());
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        //增加流通记录
        List<AppUserCirculate> appUserCirculates = new ArrayList<>();
        for (AppUserIssueRecord record : list) {
            AppUserCirculate appUserCirculate = new AppUserCirculate();
            appUserCirculate.setIsssueId(record.getId());
            appUserCirculate.setUserId(userId);
            appUserCirculate.setCirculateType(2);
            appUserCirculate.setCirculateRound(record.getCirculateRound());
            appUserCirculate.setCirculateAmount(record.getAmount());
            appUserCirculate.setCreateTime(LocalDateTime.now());
            appUserCirculate.setWaitCirculation(record.getWaitCirculation());
            appUserCirculate.setCirculateRoundRemain(record.getWaitCirculation().compareTo(BigDecimal.ZERO) > 0 ? record.getRound() - 1 : 0);
            appUserCirculates.add(appUserCirculate);
        }

        AppUserAssetsHistory appUserAssetsHistory = new AppUserAssetsHistory();
        appUserAssetsHistory.setUserId(userId);
        appUserAssetsHistory.setType(5);
        appUserAssetsHistory.setStatus(1);
        appUserAssetsHistory.setTokenId(2);
        appUserAssetsHistory.setAmount(release);
        appUserAssetsHistory.setCreateTime(LocalDateTime.now());
        appUserAssetsHistory.setUpdateTime(LocalDateTime.now());
        boolean saveHistory = appUserAssetsHistoryService.save(appUserAssetsHistory);
        if (!saveHistory) {
            log.info("分享奖励 增加历史交易日志失败！app_user_assets_history 用户id：{},增加流通数量：{}", userId, release);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        AppUserIssueHistory appUserIssueHistory = new AppUserIssueHistory();
        appUserIssueHistory.setUserId(userId);
        appUserIssueHistory.setType(5);
        appUserIssueHistory.setAmount(release);
        appUserIssueHistory.setCreateTime(LocalDateTime.now());
        appUserIssueHistoryService.save(appUserIssueHistory);
        boolean saveFlag = appUserCirculateService.saveBatch(appUserCirculates);
        if (!saveFlag) {
            log.error("分享奖励 增加流通记录失败！app_user_circulate 用户id：{},增加流通数量：{}", userId, appUserCirculates.size());
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        int updateWallet = appUserWalletService.updateUserAmountByUserIDandCoin(release, new BigDecimal("0"), release.negate(), userId, LetokenTokenTypeEnum.LET.getId());
        if (updateWallet == 0) {
            log.error("分享奖励 修改用户金额失败 app_user_wallet！用户id：{},修改金额：{}", userId, release);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        try {
            AppUserAssetsHistory updateAssetHistory = new AppUserAssetsHistory();
            updateAssetHistory.setBalance(appUserWalletMapper.getAvailableBalance(appUserAssetsHistory.getTokenId(), appUserAssetsHistory.getUserId()));
            updateAssetHistory.setId(appUserAssetsHistory.getId());
            updateAssetHistory.updateById();
        }catch (Exception e){
            log.error("更新余额失败 id{} eMsg{}", appUserAssetsHistory.getId(), e.getMessage());
        }

        int updateUserIssue = this.updateUserIssueByUseIid(new BigDecimal("0"), release, release.negate(), userId, null, null);
        if (updateUserIssue == 0) {
            log.error("分享奖励 修改用户铸币发型信息 app_user_issue！用户id：{},修改金额：{}", userId, release);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        AppUserLog appUserLog = new AppUserLog();
        appUserLog.setType(4);
        appUserLog.setUserId(userId);
        appUserLog.setTriggerId(id);
        appUserLog.setCreateTime(LocalDateTime.now());
        appUserLog.setRemarks(String.format("铸币用户：%s，直推用户：%s。用户%s铸币%s，直推用户%s获得分享奖励。释放比例：%s * 铸币金额：%s = 奖励%s。实际奖励金额：%s，奖励前待释放金额：%s，奖励后带释放金额：%s", id, userId, id, amounts, userId, rate, amounts, money, release, appUserIssue.getCirculationRemain(), appUserIssue.getCirculationRemain().subtract(release)));
        appUserLogService.save(appUserLog);

    }

    /**
     * 需求变更后的 直推奖
     *
     * @param userId  上级id
     * @param rate    比例
     * @param amounts 金额
     * @param id      铸币人id
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void mintRewardsChange(Integer userId, BigDecimal rate, BigDecimal amounts, Integer id) {
        QueryAppIssueConfigRes configMapper = adminIssueConfigManager.queryLetokenIssueConfig();
        // BigDecimalUtil.multiply(mintAmount, new BigDecimal(mintConfig.getRewardRate())).divide(new BigDecimal(100));
        //奖励金额
        BigDecimal money = rate.multiply(amounts);
        AppUserIssue appUserIssue = appUserIssueMapper.selectById(userId);
        if (appUserIssue == null || appUserIssue.getCirculationRemain().compareTo(BigDecimal.ZERO) <= 0) {
            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setType(4);
            appUserLog.setUserId(userId);
            appUserLog.setTriggerId(id);
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setRemarks(String.format("铸币用户：%s，直推用户：%s。用户%s铸币%s，直推用户%s获得分享奖励。释放比例：%s * 铸币金额：%s = 奖励%s。实际奖励金额：%s.直推用户待释放额度为0，不获取奖励", id, userId, id, amounts, userId, rate, amounts, money, "0"));
            appUserLogService.save(appUserLog);
            return;

        }
        BigDecimal dailiutong = appUserIssue.getCirculationRemain();
        /*BigDecimal release;
        if (money.compareTo(appUserIssue.getCirculationRemain()) <= 0) {
            release = money;
        } else {
            release = appUserIssue.getCirculationRemain();
        }*/

        QueryWrapper<AppUserIssueRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("status", 0).orderByAsc("create_time");
        List<AppUserIssueRecord> recordList = appUserIssueRecordService.list(queryWrapper);
        if (recordList == null || recordList.size() == 0) {
            return;
        }

        BigDecimal sumMoney = BigDecimal.ZERO;
        for (AppUserIssueRecord record : recordList) {
            //每笔订单每期释放额度
            BigDecimal money2 = record.getIssueAmount().multiply(rate);
            //AppUserIssueRecord issueRecord = new AppUserIssueRecord();
            if (money2.compareTo(record.getWaitCirculation()) > 0) {
               /* issueRecord.setWaitCirculation(BigDecimal.ZERO);
                issueRecord.setCirculation(record.getWaitCirculation().add(record.getCirculation()));*/
                sumMoney = sumMoney.add(record.getWaitCirculation());
            } else {
               /* issueRecord.setWaitCirculation(record.getWaitCirculation().subtract(money2));
                issueRecord.setCirculation(record.getCirculation().add(money2));*/
                sumMoney = sumMoney.add(money2);
            }

        }
        //一个周期的时间
        BigDecimal circulateDuration = new BigDecimal(configMapper.getCirculateDuration() * 24 * 60);
        //加速时间  分
        BigDecimal accelerateTime = money.divide(sumMoney, 2, RoundingMode.HALF_UP).multiply(circulateDuration);
        Duration duration = Duration.between(appUserIssue.getRewardTime().plusMinutes(appUserIssue.getCountDown()), LocalDateTime.now());
        //距离下个周期释放时间
        BigDecimal countDown = new BigDecimal(Math.abs((int) duration.toMinutes()));
        //加速次数
        int count = 0;
        //距离下个周期释放时间
        int gapTime = 0;
        //是否上一次释放时间
        int isUpdate = 0;
        if (accelerateTime.compareTo(countDown) < 0) {
            countDown = countDown.subtract(accelerateTime);
            int updateUserIssue = this.updateUserIssueByUseIid(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, userId, countDown.intValue(), 0);
            if (updateUserIssue == 0) {
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
            AppUserIssueHistory appUserIssueHistory = new AppUserIssueHistory();
            appUserIssueHistory.setUserId(userId);
            appUserIssueHistory.setType(5);
            appUserIssueHistory.setAmount(accelerateTime);
            appUserIssueHistory.setNewTeamIssue(amounts);
            appUserIssueHistory.setWaitCirculation(dailiutong);
            appUserIssueHistory.setOperateUserId(id);
            appUserIssueHistory.setCreateTime(LocalDateTime.now());
            appUserIssueHistoryService.save(appUserIssueHistory);

            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setType(4);
            appUserLog.setUserId(userId);
            appUserLog.setTriggerId(id);
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setRemarks(String.format("(原直推荐奖励)铸币用户：%s，直推用户：%s。用户%s铸币%s，直推用户%s获得分享奖励。释放比例：%s * 铸币金额：%s = 奖励%s。奖励前待释放金额：%s,加速周期：%s", id, userId, id, amounts, userId, rate, amounts, money, appUserIssue.getCirculationRemain(), accelerateTime));
            appUserLogService.save(appUserLog);
            return;
        } else if (accelerateTime.compareTo(countDown) >= 0 && accelerateTime.compareTo(circulateDuration) < 0) {//如果加速时间 大于等于  下一个周期释放时间 切小于  整个周期加速时间 直接释放  下个周期释放时间 = 重新计时
            count = 1;
            gapTime = circulateDuration.subtract(accelerateTime.subtract(countDown)).intValue();
            isUpdate = 1;
        } else {//如果加速时间 大于  下一个周期释放时间 直接释放 释放几期 视推荐人等级而定  3期封顶
            if (accelerateTime.compareTo(circulateDuration) == 0) {
                count = 1;
            }
            if (accelerateTime.compareTo(circulateDuration) > 0) {//加速时间 大于  固定周期释放时间
                BigDecimal result = accelerateTime.divide(circulateDuration, 2, RoundingMode.HALF_UP);
                String[] strings = result.toString().split("\\.");
                BigDecimal cycle = new BigDecimal(strings[0]);
                BigDecimal time = BigDecimal.ZERO;

                if (strings.length > 1) {
                    if (strings[1] != null && new BigDecimal(strings[1]).compareTo(BigDecimal.ZERO) > 0) {
                        time = new BigDecimal(strings[1]).divide(new BigDecimal("100")).multiply(circulateDuration);
                    }
                }
                if (time.compareTo(countDown) >= 0) {
                    count = cycle.add(new BigDecimal("1")).intValue();
                    gapTime = time.compareTo(countDown) == 0 ? circulateDuration.intValue() : circulateDuration.subtract((time.subtract(countDown))).intValue();
                    isUpdate = 1;
                } else {
                    count = cycle.intValue();
                    gapTime = countDown.subtract(time).intValue();
                    isUpdate = 0;
                }
            }
        }

        BigDecimal sumRewardsMoney = BigDecimal.ZERO;
        for (int i = 0; i < count; i++) {
            QueryWrapper<AppUserIssueRecord> queryWrappers = new QueryWrapper<>();
            queryWrappers.eq("user_id", userId).eq("status", 0).orderByAsc("create_time");
            List<AppUserIssueRecord> recordLists = appUserIssueRecordService.list(queryWrappers);
            if (recordLists == null || recordLists.size() == 0) {
                break;
            }
            if (recordLists.get(0).getIssueAmount().multiply(new BigDecimal("2")).compareTo(new BigDecimal(i)) <= 0) {
                break;
            }
            BigDecimal rewardsMoney = BigDecimal.ZERO;
            List<AppUserIssueRecord> list = new ArrayList<>();
            for (AppUserIssueRecord record : recordLists) {
                //每笔订单每期释放额度
                BigDecimal money2 = record.getIssueAmount().multiply(rate);
                AppUserIssueRecord issueRecord = new AppUserIssueRecord();
                if (money2.compareTo(record.getWaitCirculation()) > 0) {
                    issueRecord.setWaitCirculation(BigDecimal.ZERO);
                    issueRecord.setCirculation(record.getWaitCirculation().add(record.getCirculation()));
                    rewardsMoney = rewardsMoney.add(record.getWaitCirculation());
                } else {
                    issueRecord.setWaitCirculation(record.getWaitCirculation().subtract(money2));
                    issueRecord.setCirculation(record.getCirculation().add(money2));
                    rewardsMoney = rewardsMoney.add(money2);
                }
                issueRecord.setCirculateRound(record.getCirculateRound() + 1);
                issueRecord.setStatus(issueRecord.getWaitCirculation().compareTo(BigDecimal.ZERO) == 0 ? 1 : 0);
                issueRecord.setUpdateTime(LocalDateTime.now());
                issueRecord.setId(record.getId());
                issueRecord.setAmount(money2);
                list.add(issueRecord);
            }

            boolean updateFlag = appUserIssueRecordService.updateBatchById(list);
            if (!updateFlag) {
                log.info("分享奖励 修改订单记录失败！用户id：{},奖励类型：{},订单数量：{}", userId, recordList.size());
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
            AppUserAssetsHistory appUserAssetsHistory = new AppUserAssetsHistory();
            appUserAssetsHistory.setUserId(userId);
            appUserAssetsHistory.setType(4);
            appUserAssetsHistory.setStatus(1);
            appUserAssetsHistory.setTokenId(2);
            appUserAssetsHistory.setAmount(rewardsMoney);
            appUserAssetsHistory.setCreateTime(LocalDateTime.now());
            appUserAssetsHistory.setUpdateTime(LocalDateTime.now());
            boolean saveHistory = appUserAssetsHistoryService.save(appUserAssetsHistory);
            if (!saveHistory) {
                log.error("分享奖励 增加历史交易日志失败！app_user_assets_history 用户id：{},增加流通数量：{}", userId, rewardsMoney);
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }

            int updateWallet = appUserWalletService.updateUserAmountByUserIDandCoin(rewardsMoney, new BigDecimal("0"), rewardsMoney.negate(), userId, LetokenTokenTypeEnum.LET.getId());
            if (updateWallet == 0) {
                log.error("分享奖励 修改用户金额失败 app_user_wallet！用户id：{},修改金额：{}", userId, rewardsMoney);
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }

            try {
                AppUserAssetsHistory updateAssetHistory = new AppUserAssetsHistory();
                updateAssetHistory.setBalance(appUserWalletMapper.getAvailableBalance(appUserAssetsHistory.getTokenId(), appUserAssetsHistory.getUserId()));
                updateAssetHistory.setId(appUserAssetsHistory.getId());
                updateAssetHistory.updateById();
            }catch (Exception e){
                log.error("更新余额失败 id{} eMsg{}", appUserAssetsHistory.getId(), e.getMessage());
            }

            int updateUserIssue = this.updateUserIssueByUseIid(new BigDecimal("0"), rewardsMoney, rewardsMoney.negate(), userId, gapTime, isUpdate);
            if (updateUserIssue == 0) {
                log.error("分享奖励 修改用户铸币发型信息 app_user_issue！用户id：{},修改金额：{}", userId, rewardsMoney);
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
            sumRewardsMoney = sumRewardsMoney.add(rewardsMoney);
        }
        AppUserIssueHistory appUserIssueHistory = new AppUserIssueHistory();
        appUserIssueHistory.setUserId(userId);
        appUserIssueHistory.setType(5);
        appUserIssueHistory.setAmount(accelerateTime);
        appUserIssueHistory.setNewTeamIssue(amounts);
        appUserIssueHistory.setWaitCirculation(dailiutong);
        appUserIssueHistory.setOperateUserId(id);
        appUserIssueHistory.setMoney(sumRewardsMoney);
        appUserIssueHistory.setCreateTime(LocalDateTime.now());
        appUserIssueHistoryService.save(appUserIssueHistory);

        AppUserLog appUserLog = new AppUserLog();
        appUserLog.setType(4);
        appUserLog.setUserId(userId);
        appUserLog.setTriggerId(id);
        appUserLog.setCreateTime(LocalDateTime.now());
        appUserLog.setRemarks(String.format("(原直推荐奖励)铸币用户：%s，直推用户：%s。用户%s铸币%s，直推用户%s获得分享奖励。释放比例：%s * 铸币金额：%s = 奖励%s。奖励前待释放金额：%s,加速周期：%s", id, userId, id, amounts, userId, rate, amounts, money, appUserIssue.getCirculationRemain(), accelerateTime));
        appUserLogService.save(appUserLog);

    }

    /**
     * 团队动态加速
     *
     * @param userId            用户id
     * @param count             加速周期
     * @param circulateDuration 下个周期释放时间
     * @param acceleratedTime   实际加速时间】
     * @param sumTime           总共加速时间
     * @param addAmount         新增业绩
     * @param rate              释放比例
     */
    public void acceleratedRelease(Integer userId, Integer count, Integer circulateDuration, BigDecimal acceleratedTime, BigDecimal sumTime, BigDecimal addAmount, BigDecimal rate, Integer isUpdate, AppUserLog appUserLog) {
        //查询所有为流通结束的订单
        QueryWrapper<AppUserIssueRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("status", 0);
        List<AppUserIssueRecord> recordList = appUserIssueRecordService.list(queryWrapper);
        if (recordList == null || recordList.size() == 0) {
            return;
        }
        BigDecimal sumAmount = new BigDecimal("0");
        AppUserTeam appUserTeam = appUserTeamMapper.selectById(userId);
        for (int i = 0; i < count; i++) {
            List<AppUserCirculateAccelerate> accelerateList = new ArrayList<>();
            //修改订单记录
            List<AppUserIssueRecord> list = new ArrayList<>();
            if (count == null || count.equals(0)) {
                for (AppUserIssueRecord record : recordList) {
                    AppUserCirculateAccelerate accelerate = new AppUserCirculateAccelerate();
                    accelerate.setUserId(record.getUserId());
                    accelerate.setIssueId(record.getId());
                    accelerate.setTeamAmount(addAmount.intValue());
                    accelerate.setIssueAmount(appUserTeam.getUserAchievement());
                    accelerate.setEcoLevel(appUserTeam.getEcoLevel());
                    accelerate.setAccelerateMax(sumTime.intValue());
                    accelerate.setAccelerateDuration(acceleratedTime.intValue());
                    accelerate.setCreateTime(LocalDateTime.now());
                    accelerateList.add(accelerate);
                }
                break;
            }

            for (AppUserIssueRecord record : recordList) {
                if (record.getWaitCirculation().compareTo(new BigDecimal("0")) <= 0) {
                    continue;
                }
                AppUserCirculateAccelerate accelerate = new AppUserCirculateAccelerate();
                // AppUserIssueRecord issueRecord = new AppUserIssueRecord();

                BigDecimal amount = record.getIssueAmount().multiply(rate);
                BigDecimal result = record.getWaitCirculation().divide(amount, BigDecimal.ROUND_HALF_EVEN);
                String[] decimals = result.toString().split("\\.");

                record.setRound(new BigDecimal(decimals[1]).compareTo(new BigDecimal("0")) == 0 ? Integer.parseInt(decimals[0]) : Integer.parseInt(decimals[0]) + 1);
                //如果当前订单生育释放金额  小于每期数量则释放剩下全部   反之  按照每期释放金额进行释放
                if (amount.compareTo(record.getWaitCirculation()) > 0) {
                    amount = record.getWaitCirculation();
                    sumAmount = sumAmount.add(amount);
                } else {
                    sumAmount = sumAmount.add(amount);
                }

               /* accelerate.setUserId(record.getUserId());
                accelerate.setIssueId(record.getId());
                accelerate.setTeamAmount(addAmount.intValue());
                accelerate.setIssueAmount(appUserTeam.getUserAchievement());
                accelerate.setEcoLevel(appUserTeam.getEcoLevel());
                accelerate.setAccelerateMax(sumTime.intValue());
                accelerate.setAccelerateDuration(Double.valueOf(String.valueOf(acceleratedTime)).intValue());
                accelerate.setCreateTime(LocalDateTime.now());
                accelerateList.add(accelerate);*/

                record.setCirculation(record.getCirculation().add(amount));
                record.setWaitCirculation(record.getWaitCirculation().subtract(amount));
                record.setCirculateRound(record.getCirculateRound() + 1);
                record.setStatus(record.getWaitCirculation().compareTo(BigDecimal.ZERO) == 0 ? 1 : 0);
                record.setUpdateTime(LocalDateTime.now());
                record.setId(record.getId());
                record.setAmount(amount);
                // list.add(issueRecord);
                boolean updateFlag = appUserIssueRecordService.updateById(record);
                if (!updateFlag) {
                    throw new ApiServiceException(500, "mint失败，请稍后再试！");
                }
            }
            appUserCirculateAccelerateService.saveBatch(accelerateList);

        }

        AppUserAssetsHistory appUserAssetsHistory = new AppUserAssetsHistory();
        appUserAssetsHistory.setUserId(userId);
        appUserAssetsHistory.setType(4);
        appUserAssetsHistory.setStatus(1);
        appUserAssetsHistory.setTokenId(2);
        appUserAssetsHistory.setAmount(sumAmount);
        appUserAssetsHistory.setCreateTime(LocalDateTime.now());
        appUserAssetsHistory.setUpdateTime(LocalDateTime.now());
        boolean saveHistory = appUserAssetsHistoryService.save(appUserAssetsHistory);
        if (!saveHistory) {
            log.info("团队动态奖励 增加历史交易日志失败！app_user_assets_history 用户id：{},奖励类型：{},增加流通数量：{}", userId, 6, sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }
        AppUserIssue appUserIssue = appUserIssueMapper.selectById(userId);
        BigDecimal dailiutong = appUserIssue.getCirculationRemain();
        AppUserIssueHistory appUserIssueHistory = new AppUserIssueHistory();
        appUserIssueHistory.setUserId(userId);
        appUserIssueHistory.setType(6);
        appUserIssueHistory.setAmount(acceleratedTime);
        appUserIssueHistory.setNewTeamIssue(appUserTeam.getAmount());
        appUserIssueHistory.setWaitCirculation(dailiutong);
        appUserIssueHistory.setOperateUserId(appUserLog.getTriggerId());
        appUserIssueHistory.setCreateTime(LocalDateTime.now());
        appUserIssueHistoryService.save(appUserIssueHistory);
        int updateWallet = appUserWalletService.updateUserAmountByUserIDandCoin(sumAmount, new BigDecimal("0"), sumAmount.negate(), userId, LetokenTokenTypeEnum.LET.getId());
        if (updateWallet == 0) {
            log.error("团队动态奖励 修改用户金额失败 app_user_wallet！用户id：{},奖励类型：{},修改金额：{}", userId, "团队动态奖励", sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        try {
            AppUserAssetsHistory updateAssetHistory = new AppUserAssetsHistory();
            updateAssetHistory.setBalance(appUserWalletMapper.getAvailableBalance(appUserAssetsHistory.getTokenId(), appUserAssetsHistory.getUserId()));
            updateAssetHistory.setId(appUserAssetsHistory.getId());
            updateAssetHistory.updateById();
        }catch (Exception e){
            log.error("更新余额失败 id{} eMsg{}", appUserAssetsHistory.getId(), e.getMessage());
        }


        int updateUserIssue = this.updateUserIssueByUseIid(new BigDecimal("0"), sumAmount, sumAmount.negate(), userId, circulateDuration, isUpdate);
        if (updateUserIssue == 0) {
            log.error("团队动态奖励 修改用户铸币发型信息 app_user_issue！用户id：{},修改金额：{}", userId, sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。上级%s获得加速时间：%s，加速周期：%s，释放金额：%s", appUserLog.getTriggerId(), appUserLog.getUserId(), appUserLog.getUserId(), acceleratedTime, count, sumAmount));
        appUserLogService.save(appUserLog);
    }

    /**
     * 添加团队业绩
     *
     * @param userId 用户id
     * @param amount let数量
     */
    @Override
    public void addTeamValue(Integer userId, BigDecimal amount, Integer type) {
        AppUserTeamPath appUserTeamPath = appUserTeamPathMapper.selectById(userId);
        if (appUserTeamPath == null) {
            return;
        }
        if (appUserTeamPath.getInvitePath() == null || appUserTeamPath.getInvitePath() == "" || appUserTeamPath.getInvitePath() == "0") {
            return;
        }
        String[] path = appUserTeamPath.getInvitePath().split(",");
        List<AppUserTeam> teamList = new ArrayList<>();
        List<AppUserLog> logList = new ArrayList<>();
        for (String inviteID : path) {
            AppUserTeam appUserTea1 = new AppUserTeam();
            AppUserTeam appUserTeam = appUserTeamMapper.selectById(inviteID);
            if (appUserTeam == null) {
                break;
            }
            appUserTea1.setUserId(appUserTeam.getUserId());
            appUserTea1.setTeamSumValue(appUserTeam.getTeamSumValue() + amount.intValue());
            teamList.add(appUserTea1);

            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setUserId(Integer.parseInt(inviteID));
            appUserLog.setTriggerId(userId);
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setType(type);
            if (type.equals(1)) {
                appUserLog.setRemarks(String.format("绑定用户: %s，所有上级用户：%s。用户 %s绑定推荐人 %s ，增加所有上级业绩 %s,修改上级%s，上级修改前团队业绩：%s", userId, appUserTeamPath.getInvitePath(), userId, path[0], amount, appUserTeam.getTeamSumValue(), appUserTea1.getTeamValue()));
            } else {
                appUserLog.setRemarks(String.format("铸币用户: %s，所有上级用户：%s。用户%s铸币%s， 增加所有上级业绩%s，上级修改前团队业绩：%s，修改后团队业绩：%s", userId, appUserTeamPath.getInvitePath(), userId, amount, amount, appUserTeam.getTeamSumValue(), appUserTea1.getTeamValue()));
            }
            logList.add(appUserLog);
        }
        appUserTeamService.updateBatchById(teamList);
        appUserLogService.saveBatch(logList);
    }


    /**
     * 需求变更
     * 生态建设值   和   修改生态登记
     *
     * @param userId
     * @param amount
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void upgradeUPdate(Integer userId, BigDecimal amount, Integer type, AdminIssueConfig mintConfig) {
        BigDecimal money = BigDecimal.ZERO;
        List<AppEcoLevel> appEcoLevelList = appEcoLevelMapper.getAppEcoLevelInfo();
        if (appEcoLevelList.size() <= 0 || appEcoLevelList == null) {
            return;
        }
        AppUserTeamPath teamPath = appUserTeamPathMapper.selectById(userId);
        String[] path = teamPath.getInvitePath().split(",");
        List<AppUserTeam> teamList = new ArrayList<>();
        List<AppUserLog> appUserLogs = new ArrayList<>();
        Integer id = userId;
        for (String inviteID : path) {
            Integer invite = Integer.parseInt(inviteID);
            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setUserId(Integer.parseInt(inviteID));
            appUserLog.setTriggerId(userId);
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setType(type);
            AppUserTeam appUserTeam = appUserTeamMapper.selectById(inviteID);
            if (appUserTeam == null) {
                continue;
            }

            List<AppUserTeam> team = appUserTeamMapper.getMAXTeamValueSize(invite);
            if (team == null || team.size() == 0) {
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s，上级%s没有团队业绩，不获取奖励", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID));
                appUserLogService.save(appUserLog);
                continue;
            } else  {
                Integer finalId = id;
                List<AppUserTeam> appUserTeams =  team.stream().filter(t->t.getUserId().equals(finalId)).collect(Collectors.toList());
                if(appUserTeams.isEmpty()){
                    AppUserTeam userTeam =  team.get(0);
                    AppUserTeam appUserTeam1 =  appUserTeamMapper.getAchievement(finalId);
                    BigDecimal bigDecimal = new BigDecimal(userTeam.getTeamValue()).subtract(new BigDecimal(appUserTeam1.getUserAchievement()).add(new BigDecimal(appUserTeam1.getTeamSumValue())));
                    money = bigDecimal.compareTo(amount)>0 ?amount:bigDecimal;
                }else {
                    id = invite;
                    appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。该铸币人属于最大团队业绩，所以不获取奖励,上级%s最大团队业绩%s，", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), team.get(0).getTeamValue(), inviteID));
                    appUserLogService.save(appUserLog);
                    continue;
                }
            }
            appUserTeam.setEcoValue(appUserTeam.getEcoValue().add((money.multiply(mintConfig.getEcoRate()))));
            //该推荐人 团队信息
            for (AppEcoLevel appEcoLevel : appEcoLevelList) {
                if (appUserTeam.getEcoValue().compareTo(new BigDecimal(appEcoLevel.getEcoValue().toString())) >= 0) {
                    appUserTeam.setEcoLevel(appEcoLevel.getLevel());
                    break;
                }
            }
            appUserLog.setRemarks(MessageFormat.format("操作用户: {0}，所有上级用户：{1}。{2}小区团队业绩为{3}，,改变后生态建设值{4}和等级{5},铸币金额:{6}绑定上级为0", userId, teamPath.getInvitePath(), inviteID, appUserTeam.getEcoValue(), appUserTeam.getEcoLevel(), amount));
            teamList.add(appUserTeam);
            appUserLogs.add(appUserLog);
            id = invite;
        }
        appUserTeamService.updateBatchById(teamList);
        appUserLogService.saveBatch(appUserLogs);

    }

    /**
     * @param appUserIssue 铸币汇总
     * @param type         4。周期流通  5。直推 6。团队
     * @param isRewardTime 0。不改变奖励时间 1。改变奖励时间
     * @param countDown    0。不该距离下个周期释放时间  >0 修改时间
     * @param rate         释放比例
     * @param no           直推 团队不为空 周期释放为空
     */
    @Override
    public BigDecimal circulate(AppUserIssue appUserIssue, Integer type, Integer isRewardTime, Integer countDown, BigDecimal rate, String no, Integer operateUserId, BigDecimal newTeamIssue, BigDecimal addTime) {

        log.info("用户+" + appUserIssue.getUserId() + "+进行释放，类型：4。周期流通  5。直推 6。团队" + type + "上一次释放时间" + appUserIssue.getRewardTime() + "距离下一次释放时间（数据库保存）:" + appUserIssue.getCountDown() + ",根据当前计算后得到下一个释放时间差值:" + countDown + "当前时间" + LocalDateTime.now());

        //查询释放比例
        //1。查询所有用户所有待释放铸币记录
        QueryWrapper<AppUserIssueRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", appUserIssue.getUserId()).eq("status", 0).gt("wait_circulation", 0);
        List<AppUserIssueRecord> recordList = appUserIssueRecordService.list(queryWrapper);
        log.info(MessageFormat.format("用户{0}进行释放，待释放类型{1}条，释放类型{2}(1。周期流通  2。直推 3。团队)", appUserIssue.getUserId(), recordList.size(), type));
        if (recordList == null || recordList.size() == 0) {
            return BigDecimal.ZERO;

        }
       // LocalDateTime endTime = LocalDateTime.of(2023, 06, 01, 00, 00, 00);
        LocalDateTime time = LocalDateTime.now();
        //2。所有铸币记录释放一个周期
        BigDecimal sumAmount = new BigDecimal("0");
        for (AppUserIssueRecord record : recordList) {
            BigDecimal amount = record.getIssueAmount().multiply(rate);
            /*if(record.getCreateTime().isBefore(endTime)){
                amount = record.getIssueAmount().multiply(new BigDecimal("0.05"));
            }*/
            //如果当前订单生育释放金额  小于每期数量则释放剩下全部   反之  按照每期释放金额进行释放
            if (amount.compareTo(record.getWaitCirculation()) > 0) {
                amount = record.getWaitCirculation();
                sumAmount = sumAmount.add(amount);
            } else {
                sumAmount = sumAmount.add(amount);
            }
            record.setCirculation(record.getCirculation().add(amount));
            record.setWaitCirculation(record.getWaitCirculation().subtract(amount));
            record.setCirculateRound(record.getCirculateRound() + 1);
            record.setStatus(record.getWaitCirculation().compareTo(BigDecimal.ZERO) == 0 ? 1 : 0);
            record.setUpdateTime(LocalDateTime.now());
            record.setId(record.getId());
            record.setAmount(amount);
            boolean updateFlag = appUserIssueRecordService.updateById(record);
            if (!updateFlag) {
                log.info(MessageFormat.format("用户{0}释放失败，修改待释放记录失败！释放类型{1}(1。周期流通  2。直推 3。团队)", appUserIssue.getUserId(), type));
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
        }
        //插入释放记录
        AppUserAssetsHistory appUserAssetsHistory = new AppUserAssetsHistory();
        appUserAssetsHistory.setUserId(appUserIssue.getUserId());
        appUserAssetsHistory.setType(4);
        appUserAssetsHistory.setStatus(1);
        appUserAssetsHistory.setSn(no);
        appUserAssetsHistory.setTokenId(2);
        appUserAssetsHistory.setAmount(sumAmount);
        appUserAssetsHistory.setCreateTime(time);
        appUserAssetsHistory.setUpdateTime(time);
        boolean saveHistory = appUserAssetsHistoryService.save(appUserAssetsHistory);
        if (!saveHistory) {
            log.info(MessageFormat.format("用户{0}释放失败，插入资金流水失败！释放类型{1}(1。周期流通  2。直推 3。团队)", appUserIssue.getUserId(), type));
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }
        int updateUserIssue = this.updateUserIssueByUseIid(new BigDecimal("0"), sumAmount, sumAmount.negate(), appUserIssue.getUserId(), countDown, isRewardTime);
        if (updateUserIssue == 0) {
            log.error("团队动态奖励 修改用户铸币发型信息 app_user_issue！用户id：{},修改金额：{}", appUserIssue.getUserId(), sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        int updateWallet = appUserWalletService.updateUserAmountByUserIDandCoin(sumAmount, new BigDecimal("0"), sumAmount.negate(), appUserIssue.getUserId(), LetokenTokenTypeEnum.LET.getId());
        if (updateWallet == 0) {
            log.error("修改用户金额失败 app_user_wallet！用户id：{},奖励类型：{},修改金额：{}", appUserIssue.getUserId(), type, sumAmount);
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }

        try {
            AppUserAssetsHistory updateAssetHistory = new AppUserAssetsHistory();
            updateAssetHistory.setBalance(appUserWalletMapper.getAvailableBalance(appUserAssetsHistory.getTokenId(), appUserAssetsHistory.getUserId()));
            updateAssetHistory.setId(appUserAssetsHistory.getId());
            updateAssetHistory.updateById();
        }catch (Exception e){
            log.error("更新余额失败 id{} eMsg{}", appUserAssetsHistory.getId(), e.getMessage());
        }
        //记录log 日志
        QueryWrapper<AppUserIssue> queryWrappers = new QueryWrapper<>();
        queryWrappers.eq("user_id", appUserIssue.getUserId());
        AppUserIssue issue = appUserIssueMapper.selectOne(queryWrappers);
        AppUserLog appUserLog = new AppUserLog();
        appUserLog.setUserId(appUserIssue.getUserId());
        appUserLog.setCreateTime(time);
        if (type.equals(4)) {
            appUserLog.setType(6);
            appUserLog.setRemarks(MessageFormat.format("用户：{0}进行周期释放{1}，释放前待流通：{2}，释放后带流通：{3}，释放前上一次奖励时间：{4},释放后奖励时间：{5},修改后距离下一周期释放时间（分钟）：{6}当前时间：{7}", appUserIssue.getUserId(), sumAmount, appUserIssue.getCirculationRemain(), issue.getCirculationRemain(), appUserIssue.getRewardTime(), issue.getRewardTime(), issue.getCountDown(), time));
        } else if (type.equals(5)) {
            appUserLog.setType(7);
            appUserLog.setTriggerId(operateUserId);
            appUserLog.setRemarks(MessageFormat.format("用户：{0}获得下级{9}铸币{10}直推奖励释放{1}，释放前待流通：{2}，释放后待流通：{3}，释放前上一次奖励时间：{4},释放后奖励时间：{5},修改后距离下一周期释放时间（分钟）：{6}当前时间：{7},获得加速时间：{8}", appUserIssue.getUserId(), sumAmount, appUserIssue.getCirculationRemain(), issue.getCirculationRemain(), appUserIssue.getRewardTime(), issue.getRewardTime(), issue.getCountDown(), time, addTime, operateUserId, newTeamIssue));
        } else {
            appUserLog.setType(8);
            appUserLog.setTriggerId(operateUserId);
            appUserLog.setRemarks(MessageFormat.format("用户：{0}获得小区用户{9}铸币{10}团队奖励释放{1}，释放前待流通：{2}，释放后待流通：{3}，释放前上一次奖励时间：{4},释放后奖励时间：{5},修改后距离下一周期释放时间（分钟）：{6}当前时间：{7},获得加速时间：{8}", appUserIssue.getUserId(), sumAmount, appUserIssue.getCirculationRemain(), issue.getCirculationRemain(), appUserIssue.getRewardTime(), issue.getRewardTime(), issue.getCountDown(), time, addTime, operateUserId, newTeamIssue));
        }

        appUserLog.setUuid(no);
        appUserLogService.save(appUserLog);
       // log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+sumAmount);
        return sumAmount;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void mintRewardsChangeV2(AppUserTeam appUserTeam, String no,AdminIssueConfig adminIssueConfig) {
        BigDecimal amount = appUserTeam.getAmount();
        Integer userId = appUserTeam.getInviterId();
        Integer operateId = appUserTeam.getUserId();
        AppUserIssue appUserIssue = appUserIssueMapper.selectById(userId);
        LocalDateTime dateTime = LocalDateTime.now();
        if (appUserIssue == null || appUserIssue.getCirculationRemain().compareTo(BigDecimal.ZERO) <= 0) {
            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setType(4);
            appUserLog.setUserId(userId);
            appUserLog.setTriggerId(operateId);
            appUserLog.setCreateTime(dateTime);
            appUserLog.setRemarks(String.format("铸币用户：%s，直推用户：%s。用户%s铸币%s.直推用户待释放额度为0，不获取奖励", operateId, userId, operateId, amount));
            if(!appUserLogService.save(appUserLog)){
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
            return;
        }
        QueryWrapper<AppUserIssueRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("status", 0).orderByAsc("create_time");
        List<AppUserIssueRecord> recordList = appUserIssueRecordService.list(queryWrapper);
        if (recordList == null || recordList.size() == 0) {
            return ;
        }
        LocalDateTime endTime = LocalDateTime.of(2023, 06, 01, 00, 00, 00);
        BigDecimal rate = new BigDecimal(adminIssueConfig.getCirculateRate()).divide(new BigDecimal("100"));
        BigDecimal sumMoney = BigDecimal.ZERO;
        for (AppUserIssueRecord record : recordList) {
            BigDecimal money2 = record.getIssueAmount().multiply(rate);
            if(record.getCreateTime().isBefore(endTime)){
                money2 = record.getIssueAmount().multiply(new BigDecimal("0.05"));
            }
            //每笔订单每期释放额度

            if (money2.compareTo(record.getWaitCirculation()) > 0) {
                sumMoney = sumMoney.add(record.getWaitCirculation());
            } else {
                sumMoney = sumMoney.add(money2);
            }
        }
        BigDecimal circulateDuration = new BigDecimal(adminIssueConfig.getCirculateDuration() * 24 * 60);
        BigDecimal decimal = amount.multiply(rate).multiply(circulateDuration).divide(sumMoney, 2, RoundingMode.HALF_UP);
        acceleratedRewards(appUserIssue, operateId, amount, 5, no,decimal,BigDecimal.ZERO);
    }

    @Override
    public void ecologicalRewardsV2(AppUserTeam appUserTeam, String no,AdminIssueConfig adminIssueConfig) {
        final BigDecimal amount = appUserTeam.getAmount(), rate = appUserTeam.getRate();
        String pathStr = appUserTeamPathMapper.checkoutAppUserTeam(appUserTeam.getUserId());
        if (StringUtils.isEmpty(pathStr)) {
            return;
        }
        String[] path = pathStr.split(",");
        // 发行用户的ID
        Integer operateId = appUserTeam.getUserId();
        Integer id = operateId;
        for (String inviteID : path) {
            Integer invite = Integer.valueOf(inviteID);
            AppUserLog appUserLog = new AppUserLog();
            appUserLog.setUserId(invite);
            appUserLog.setTriggerId(operateId);
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setUuid(no);
            appUserLog.setType(5);
            List<AppUserTeam> team = appUserTeamMapper.getMAXTeamValueSize(invite);
            if (team == null || team.size() == 0) {
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s，上级%s没有团队业绩，不获取奖励", operateId, inviteID, operateId, appUserTeam.getAmount(), inviteID));
                appUserLogService.save(appUserLog);
                continue;
            } else if (team.size() == 1) {
                AppUserTeam teams = team.get(0);
                Integer amout = appUserTeamMapper.getSUMTeamValue(invite, teams.getUserId());
                if ((teams.getUserId().equals(id)) || appUserTeamMapper.getCount(invite, id) <= 0) {
                    id = invite;
                    appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。该铸币人属于最大团队业绩，所以不获取奖励,上级%s最大团队业绩%s，", operateId, inviteID, operateId, appUserTeam.getAmount(), inviteID, team.get(0).getTeamValue()));
                    if(!appUserLogService.save(appUserLog)){
                        throw new ApiServiceException(500, "mint失败，请稍后再试！");
                    }
                    continue;
                }
            }
            AppUserIssue appUserIssue = appUserIssueMapper.selectById(invite);
            AppUserTeam appUserTeam2 = appUserTeamMapper.selectById(invite);
            if (appUserTeam2.getUserAchievement() == null || appUserTeam2.getUserAchievement().equals(0) || appUserIssue == null || appUserIssue.getCirculationRemain().compareTo(BigDecimal.ZERO) <= 0) {
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。用户%s铸币%s。上级%s个人业绩为0，不获取奖励", appUserTeam.getUserId(), inviteID, appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID));
                if(!appUserLogService.save(appUserLog)){
                    throw new ApiServiceException(500, "mint失败，请稍后再试！");
                }
                continue;
            }

            BigDecimal circulateDuration = new BigDecimal(adminIssueConfig.getCirculateDuration() * 24 * 60);
            BigDecimal maxAccelerate =  new BigDecimal(adminIssueConfig.getMaxAccelerate()* 24 * 60);
            //计算加速时间
            BigDecimal decimal = amount.multiply(circulateDuration).divide(appUserIssue.getCirculationRemain().divide(new BigDecimal("2")), 2, RoundingMode.HALF_UP);
            //直推用户信息
            AppUserTeam appUserTeam3 = appUserTeamMapper.selectById(id);
            //一条线 最大加速 与 已拿到加速时间对比  最大加速大于 已拿到时间 返回 最大加速 - 已拿到时间  否则不给奖励
            BigDecimal maxTime = maxAccelerate.compareTo(appUserTeam3.getAccelerateTime()) > 0 ? maxAccelerate.subtract(appUserTeam3.getAccelerateTime()) : BigDecimal.ZERO;
            if(maxTime.compareTo(BigDecimal.ZERO) <= 0){
                id = invite;
                appUserLog.setRemarks(String.format("铸币用户：%s，所有上级：%s。直推用户%s已给上级带来%s加速时间，达到当日上限，用户%s铸币%s。上级%s个人业绩为0，不获取奖励", appUserTeam.getUserId(), inviteID,id,appUserTeam3.getAccelerateTime(), appUserTeam.getUserId(), appUserTeam.getAmount(), inviteID));
                if(!appUserLogService.save(appUserLog)){
                    throw new ApiServiceException(500, "mint失败，请稍后再试！");
                }
                continue;
            }
            //一条线还可以拿多少奖励   当前获得加速时间 对比  剩余可拿加速时间  返回剩余加速时间  否则  则加速当前获得全部奖励时间
            maxTime = decimal.compareTo(maxTime) >= 0 ? maxTime : decimal;
            AppUserTeam team1 = new AppUserTeam();
            team1.setUserId(appUserTeam3.getUserId());
            team1.setAccelerateTime(appUserTeam3.getAccelerateTime().add(maxTime));
            if(appUserTeamMapper.updateById(team1)<1){
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
            acceleratedRewards(appUserIssue, operateId, amount, 6, no,maxTime,decimal);
            id = invite;
        }
    }


    /**
     * @param appUserIssue
     * @param operateId    发行用户
     * @param amount       金额
     * @param type         类型 5。直推  6。动态
     * @param no
     */
    public BigDecimal acceleratedRewards(AppUserIssue appUserIssue, Integer operateId, BigDecimal amount, Integer type, String no,BigDecimal decimal,BigDecimal maxDecimal) {

        Integer userId = appUserIssue.getUserId();

        QueryAppIssueConfigRes adminIssueConfig = adminIssueConfigManager.queryLetokenIssueConfig();
        BigDecimal rate = new BigDecimal(adminIssueConfig.getCirculateRate()).divide(new BigDecimal("100"));
        //一个周期时间 换算成分钟
        BigDecimal circulateDuration = new BigDecimal(adminIssueConfig.getCirculateDuration() * 24 * 60);

        AppUserLog appUserLog = new AppUserLog();
        BigDecimal ss = decimal;
        //距离下个周期释放时间 上一次奖励时间 + 距离下个周期释放时间  与当前时间对比
        Duration durations = Duration.between(appUserIssue.getRewardTime().plusMinutes(appUserIssue.getCountDown()), LocalDateTime.now());
        BigDecimal countDown = new BigDecimal(Math.abs((int) durations.toMinutes()));
        BigDecimal count = countDown;
        BigDecimal sumAmount = BigDecimal.ZERO;
        log.info("用户+" + appUserIssue.getUserId() + "+获得直推奖励加速时间：" + decimal + "分钟," + "上一次释放时间" + appUserIssue.getRewardTime() + "距离下一次释放时间（数据库保存）:" + appUserIssue.getCountDown() + ",根据当前计算后得到下一个释放时间差值:" + countDown + "当前时间" + LocalDateTime.now());
        AppUserIssueHistory appUserIssueHistory = new AppUserIssueHistory();
        appUserIssueHistory.setUserId(userId);
        appUserIssueHistory.setType(type);
        appUserIssueHistory.setAmount(decimal);
        appUserIssueHistory.setNewTeamIssue(amount);
        appUserIssueHistory.setWaitCirculation(appUserIssue.getCirculationRemain());
        appUserIssueHistory.setOperateUserId(operateId);
        appUserIssueHistory.setCreateTime(LocalDateTime.now());
        appUserIssueHistory.setUuid(no);
        if(!appUserIssueHistoryService.save(appUserIssueHistory)){
            throw new ApiServiceException(500, "mint失败，请稍后再试！");
        }
        try {
            while (decimal.compareTo(circulateDuration) >= 0) {
                BigDecimal sss = circulate(appUserIssue, type, 0, 0, rate, no, operateId, amount, ss);
                if(sss.compareTo(BigDecimal.ZERO)<=0){
                    return ss;
                }
                sumAmount = sumAmount.add(sss);
                decimal = decimal.subtract(circulateDuration);
            }

            if (decimal.compareTo(countDown) >= 0 && decimal.compareTo(circulateDuration) < 0) {
                countDown = circulateDuration.subtract(decimal.subtract(countDown));
                sumAmount = sumAmount.add(circulate(appUserIssue, type, 1, countDown.intValue(), rate, no, operateId, amount, ss));
                return ss;
            }

            if (decimal.compareTo(countDown) < 0) {
                countDown = countDown.subtract(decimal);
                int updateUserIssue = this.updateUserIssueByUseIid(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, userId, countDown.intValue(), 1);
                if (updateUserIssue == 0) {
                    throw new ApiServiceException(500, "mint失败，请稍后再试！");
                }
               /* AppUserIssue issue = appUserIssueMapper.selectById(userId);
                appUserLog.setRemarks(String.format("铸币用户：%s，拿到奖励用户：%s。用户%s铸币%s。获得加速时间：%s，获的奖励前距离下个周期释放时间：%s,加速后距离下个周期释放时间：%s,加速前上一次奖励时间：%s，加速后上一次奖励时间：%s",
                        operateId, userId, operateId, amount, ss, appUserIssue.getCountDown(), issue.getCountDown(), appUserIssue.getRewardTime(), issue.getRewardTime()));*/
            }
        } finally {
            appUserLog.setUserId(userId);
            appUserLog.setTriggerId(operateId);
            appUserLog.setCreateTime(LocalDateTime.now());
            appUserLog.setUuid(no);
            appUserLog.setType(type.equals(6) ? 5 : 4);
            AppUserIssue issue = appUserIssueMapper.selectById(userId);
            appUserLog.setRemarks(String.format("铸币用户：%s，拿到奖励用户：%s。用户%s铸币%s。获得加速时间：%s，获的奖励前距离下个周期释放时间：%s,按照当前时间距离时间：%s,加速后距离下个周期释放时间：%s,加速前上一次奖励时间：%s，加速后上一次奖励时间：%s,加速总金额：%s。(实际获得奖励时间：%s，加速时间：%s)", operateId, userId, operateId, amount, ss, appUserIssue.getCountDown(), count, issue.getCountDown(), appUserIssue.getRewardTime(), issue.getRewardTime(), sumAmount, decimal, maxDecimal));
            if (!appUserLogService.save(appUserLog)) {
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
        }
        return ss;
    }


    @Resource
    AppUserIssueRecordMapper appUserIssueRecordMapper;
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void circulatesss() {
        List<Integer> ids = appUserIssueRecordMapper.getUserId();
        for (Integer id : ids) {
            List<AppUserIssueRecord> appUserIssueRecord = appUserIssueRecordMapper.getRecord(id);

            LocalDateTime time = LocalDateTime.now();
            //2。所有铸币记录释放一个周期
            BigDecimal sumAmount = new BigDecimal("0");
            for (AppUserIssueRecord record : appUserIssueRecord) {
                BigDecimal amount = record.getIssueAmount().multiply(new BigDecimal("0.01"));

                //如果当前订单生育释放金额  小于每期数量则释放剩下全部   反之  按照每期释放金额进行释放
                if (amount.compareTo(record.getWaitCirculation()) > 0) {
                    amount = record.getWaitCirculation();
                    sumAmount = sumAmount.add(amount);
                } else {
                    sumAmount = sumAmount.add(amount);
                }
                record.setCirculation(record.getCirculation().add(amount));
                record.setWaitCirculation(record.getWaitCirculation().subtract(amount));
                record.setCirculateRound(record.getCirculateRound() + 1);
                record.setStatus(record.getWaitCirculation().compareTo(BigDecimal.ZERO) == 0 ? 1 : 0);
                record.setUpdateTime(LocalDateTime.now());
                record.setId(record.getId());
                record.setAmount(amount);
                boolean updateFlag = appUserIssueRecordService.updateById(record);
                if (!updateFlag) {
                    throw new ApiServiceException(500, "mint失败，请稍后再试！");
                }
            }
            //插入释放记录
            AppUserAssetsHistory appUserAssetsHistory = new AppUserAssetsHistory();
            appUserAssetsHistory.setUserId(id);
            appUserAssetsHistory.setType(4);
            appUserAssetsHistory.setStatus(1);
            //appUserAssetsHistory.setSn(no);
            appUserAssetsHistory.setTokenId(2);
            appUserAssetsHistory.setAmount(sumAmount);
            appUserAssetsHistory.setCreateTime(time);
            appUserAssetsHistory.setUpdateTime(time);
            boolean saveHistory = appUserAssetsHistoryService.save(appUserAssetsHistory);
            if (!saveHistory) {
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }
            int updateUserIssue = this.updateUserIssueByUseIid(new BigDecimal("0"), sumAmount, sumAmount.negate(), id, 0, 0);
            if (updateUserIssue == 0) {
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }

            int updateWallet = appUserWalletService.updateUserAmountByUserIDandCoin(sumAmount, new BigDecimal("0"), sumAmount.negate(), id, LetokenTokenTypeEnum.LET.getId());
            if (updateWallet == 0) {
                throw new ApiServiceException(500, "mint失败，请稍后再试！");
            }

            try {
                AppUserAssetsHistory updateAssetHistory = new AppUserAssetsHistory();
                updateAssetHistory.setBalance(appUserWalletMapper.getAvailableBalance(appUserAssetsHistory.getTokenId(), appUserAssetsHistory.getUserId()));
                updateAssetHistory.setId(appUserAssetsHistory.getId());
                updateAssetHistory.updateById();
            }catch (Exception e){
                log.error("更新余额失败 id{} eMsg{}", appUserAssetsHistory.getId(), e.getMessage());
            }
            // log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+sumAmount);
        }
    }

    @Resource
    AppMallIssueMapper appMallIssueMapper;
    /**
     * 平级奖
     * @param userId
     * @param amount
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void peerLevelReward(Integer userId,BigDecimal amount,String no){
       BigDecimal rate = appMallIssueMapper.getMaxLevelRate();
       List<UserLevelReq> user = appMallIssueMapper.selectUserLevel(userId);
       //上一次拿奖励的人等级
       Integer level = 0;
       BigDecimal levelRate = BigDecimal.ZERO;
       if(user.size()>0){
           for (UserLevelReq req:user) {
               if(req.getLevel() > level && rate.compareTo(BigDecimal.ZERO) > 0){

                   if (!calculateConsumerValue.hasKey(calculateConsumerValue.getKey(), String.valueOf(req.getUserId())) && !calculateConsumerValue.isNewUser(req.getUserId())){
                       log.info("服务奖：用户{}不满足消费值条件",req.getUserId());
                       continue;
                   }

                   log.info("用户id"+req.getUserId());
                   BigDecimal rates= req.getRate();
                   log.info("用户比例"+rates);
                   req.setRate(req.getRate().subtract(levelRate));
                   log.info("用户极差后比例"+req.getRate());
                   BigDecimal ss = rate.compareTo(req.getRate())>0?req.getRate():rate;
                   log.info("用作奖励比例"+ss);
                   BigDecimal reward = amount.multiply(ss);
                   rate = rate.compareTo(req.getRate())>0?rate.subtract(req.getRate()):BigDecimal.ZERO;
                   log.info("剩余奖励比例"+ss);
                   level=req.getLevel();
                   levelRate = rates;
                   AppUserAssetsHistory appUserAssetsHistory = new AppUserAssetsHistory();
                   appUserAssetsHistory.setUserId(req.getUserId());
                   appUserAssetsHistory.setType(TokenTransactionTypeEnum.PEER_LEVEL_REWARD.getValue());
                   appUserAssetsHistory.setStatus(1);
                   appUserAssetsHistory.setSn(no);
                   appUserAssetsHistory.setTokenId(2);
                   appUserAssetsHistory.setAmount(reward);
                   appUserAssetsHistory.setCreateTime(LocalDateTime.now());
                   appUserAssetsHistory.setUpdateTime(LocalDateTime.now());
                   boolean saveHistory = appUserAssetsHistoryService.save(appUserAssetsHistory);
                   if (!saveHistory) {
                       throw new ApiServiceException(500, "mint失败，请稍后再试！");
                   }

                   int updateWallet = appUserWalletService.updateUserAmountByUserIDandCoin(reward, new BigDecimal("0"),BigDecimal.ZERO, req.getUserId(), LetokenTokenTypeEnum.LET.getId());
                   if (updateWallet == 0) {
                       throw new ApiServiceException(500, "mint失败，请稍后再试！");
                   }

                   try {
                       AppUserAssetsHistory updateAssetHistory = new AppUserAssetsHistory();
                       updateAssetHistory.setBalance(appUserWalletMapper.getAvailableBalance(appUserAssetsHistory.getTokenId(), appUserAssetsHistory.getUserId()));
                       updateAssetHistory.setId(appUserAssetsHistory.getId());
                       updateAssetHistory.updateById();
                   }catch (Exception e){
                       log.error("更新余额失败 id{} eMsg{}", appUserAssetsHistory.getId(), e.getMessage());
                   }
               }
           }
       }

    }

    @Resource
    private AppIssueCardInfoMapper appIssueCardInfoMapper;
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void useCoupons(Integer cardId,AdminIssueConfig adminIssueConfig) {
        Integer userId = WebUtils.getUserId();
        QueryWrapper<AppIssueCardInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("state",1).eq("id",cardId);
        AppIssueCardInfo info = appIssueCardInfoMapper.selectOne(queryWrapper);
        if(info == null){
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_040);
        }
        QueryWrapper<AppUserIssueRecord> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("user_id", userId).eq("status", 0).orderByAsc("create_time");
        List<AppUserIssueRecord> recordList = appUserIssueRecordService.list(queryWrapper2);
        if (recordList == null || recordList.size() == 0) {
            return ;
        }
        LocalDateTime endTime = LocalDateTime.of(2023, 06, 01, 00, 00, 00);
        BigDecimal rate = new BigDecimal(adminIssueConfig.getCirculateRate()).divide(new BigDecimal("100"));
        BigDecimal sumMoney = BigDecimal.ZERO;
        for (AppUserIssueRecord record : recordList) {
            BigDecimal money2 = record.getIssueAmount().multiply(rate);
            if(record.getCreateTime().isBefore(endTime)){
                money2 = record.getIssueAmount().multiply(new BigDecimal("0.05"));
            }
            //每笔订单每期释放额度
            if (money2.compareTo(record.getWaitCirculation()) > 0) {
                sumMoney = sumMoney.add(record.getWaitCirculation());
            } else {
                sumMoney = sumMoney.add(money2);
            }
        }
        BigDecimal circulateDuration = new BigDecimal(adminIssueConfig.getCirculateDuration() * 24 * 60);
        BigDecimal decimal = info.getAcceleration().multiply(circulateDuration).divide(sumMoney, 2, RoundingMode.HALF_UP);
        QueryWrapper<AppUserIssue> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("user_id", userId);
        AppUserIssue appUserIssue = appUserIssueMapper.selectOne(queryWrapper1);
        if (appUserIssue != null && appUserIssue.getCirculationRemain().compareTo(BigDecimal.ZERO)>0) {
            acceleratedRewards(appUserIssue, userId, BigDecimal.ZERO, 7, cardId.toString(),decimal,BigDecimal.ZERO);
            info.setState(2);
            info.updateById();
        }else {
            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_MALL_SMS_040);
        }
    }
}
